package org.gdstash.description;

import org.gdstash.db.*;
import org.gdstash.util.GDMsgFormatter;
import org.gdstash.util.GDMsgLogger;

import java.util.LinkedList;
import java.util.List;

public class BonusDetail {
    public static final int TYPE_STAT = 1;
    public static final int TYPE_SKILLBONUS = 2;
    public static final int TYPE_SKILL = 3;
    public static final int TYPE_SKILLMODIFIER = 4;
    public Object entity;
    public int type;
    public List<BonusInfo> infos;

    public BonusDetail(final DBStashItem item, final int detailType, final DBStat stat, final String prefix) {
        this.entity = stat;
        this.type = 1;
        this.infos = createStatInfos(item, detailType, stat, prefix);
    }

    public BonusDetail(final DBStashItem item, final int detailType, final DBStat stat, final DBSkillModifier skillModifier) {
        this.entity = stat;
        this.type = 1;
        this.infos = createStatInfos(item, detailType, stat, skillModifier);
    }

    public BonusDetail(final DBSkillBonus skillBonus) {
        this.entity = skillBonus;
        this.type = 2;
        this.infos = new LinkedList<BonusInfo>();
        this.createSkillBonusInfos(null);
    }

    public BonusDetail(final DBStashItem item, final DBSkillBonus skillBonus) {
        this.entity = skillBonus;
        this.type = 2;
        this.infos = new LinkedList<BonusInfo>();
        this.createSkillBonusInfos(item);
    }

    public BonusDetail(final DBSkill skill) {
        this.entity = skill;
        this.type = 3;
        this.infos = createSkillInfos(skill);
    }

    public BonusDetail(final DBSkill skill, final DBStat stat) {
        this.entity = skill;
        this.type = 3;
        this.infos = createSkillInfos(skill, stat);
    }

    public BonusDetail(final DBSkill skill, final DBStat stat, final String prefix) {
        this.entity = skill;
        this.type = 3;
        this.infos = createSkillInfos(skill, stat, prefix);
    }

    public BonusDetail(final DBSkillModifier skillModifier) {
        this.entity = skillModifier;
        this.type = 4;
        this.infos = new LinkedList<BonusInfo>();
        this.createSkillModifierInfos();
    }

    private static List<BonusInfo> createSkillInfos(final DBSkill skill) {
        final List<BonusInfo> list = new LinkedList<BonusInfo>();
        final String skillName = skill.getName();
        if (skillName != null) {
            final BonusInfo info = new BonusInfo();
            final Object[] sargs = {skillName};
            info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_SKILL_GRANTED", sargs);
            list.add(info);
        }
        return list;
    }

    public static List<BonusInfo> createStatInfos(final DBStashItem item, final int detailType, final DBStat stat, final String prefix) {
        if (stat.getStatType() == null) {
            return null;
        }
        final TagInfo info = TagInfoHashMap.getInfo(stat.getStatType());
        if (info == null) {
            return null;
        }
        if (info.getTag() != null) {
            return parseStat(item, detailType, stat, prefix, null, info, false);
        }
        return null;
    }

    public static List<BonusInfo> createStatInfos(final DBStashItem item, final int detailType, final DBStat stat, final DBSkillModifier skillModifier) {
        if (stat.getStatType() == null) {
            return null;
        }
        final TagInfo info = TagInfoHashMap.getInfo(stat.getStatType());
        if (info == null) {
            return null;
        }
        if (info.getTag() != null) {
            return parseStat(item, detailType, stat, null, skillModifier, info, false);
        }
        return null;
    }

    public static List<BonusInfo> createStatInfos(final List<DBStat> stats, final String prefix) {
        final List<BonusInfo> infos = new LinkedList<BonusInfo>();
        if (stats == null) {
            return null;
        }
        for (final DBStat stat : stats) {
            if (stat.getStatType() == null) {
                continue;
            }
            final TagInfo info = TagInfoHashMap.getInfo(stat.getStatType());
            if (info == null) {
                continue;
            }
            if (info.getTag() == null) {
                continue;
            }
            final List<BonusInfo> temp = parseStat(null, 1, stat, prefix, null, info, true);
            infos.addAll(temp);
        }
        return infos;
    }

    private static String buildText(final String tag, final List<Object> lArgs) {
        final Object[] args = new Object[lArgs.size()];
        int i = 0;
        for (final Object o : lArgs) {
            args[i] = o;
            ++i;
        }
        final String text = GDMsgFormatter.format(GDMsgFormatter.rbGD, tag, args);
        return text;
    }

    private static int adjustValue(final DBStashItem item, final int detailType, final int value) {
        if (item == null) {
            return value;
        }
        int result = value;
        if (item == null) {
            return result;
        }
        if (detailType == 1 && item.isComponent()) {
            final int pieces = item.getComponentPieces();
            int var1 = item.getVar1();
            if (var1 == 0) {
                var1 = 1;
            }
            if (var1 < pieces) {
                float f = (float) result;
                f = (float) (f * var1 / pieces + 0.5);
                result = (int) f;
                if (result < 1) {
                    result = 1;
                }
            }
        }
        if (detailType == 2 && item.getDBComponent() != null) {
            final int pieces = item.getComponentPieces();
            int var1 = item.getVar1();
            if (var1 == 0) {
                var1 = 1;
            }
            if (var1 < pieces) {
                float f = (float) result;
                f = (float) (f * var1 / pieces + 0.5);
                result = (int) f;
                if (result < 1) {
                    result = 1;
                }
            }
        }
        return result;
    }

    private static List<BonusInfo> fillRaceBonus(final int detailType, final DBStat stat, final String prefix, final TagInfo tagInfo, final boolean blankStat) {
        final List<BonusInfo> infos = new LinkedList<BonusInfo>();
        BonusInfo info = null;
        final DBStatBonusRace br = stat.getBonusRace();
        if (br == null) {
            return infos;
        }
        final Object[] args = {stat.getStatMin(), br.getRaceName()};
        final String statDesc = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_UNI_RACE_DAMAGE", args);
        info = new BonusInfo(tagInfo);
        info.prefix = prefix;
        info.dmgPerc = true;
        final String tag = "TXT_UNI_RACE_DAMAGE";
        info.text = statDesc;
        infos.add(info);
        return infos;
    }

    private static List<BonusInfo> parseCharStat(final DBStashItem item, final int detailType, final DBStat stat, final String prefix, final DBSkillModifier skillModifier, final TagInfo tagInfo, final boolean blankStat) {
        final List<BonusInfo> infos = new LinkedList<BonusInfo>();
        String tag = null;
        List<Object> lArgs = null;
        BonusInfo info = null;
        String statDesc = GDMsgFormatter.getString(GDMsgFormatter.rbGD, tagInfo.getTag());
        if (prefix != null) {
            final Object[] args = {prefix, statDesc};
            statDesc = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_STAT_PREFIX", args);
        }
        if (statDesc.equals("")) {
            return infos;
        }
        if (stat.getStatMin() != 0.0f) {
            lArgs = new LinkedList<Object>();
            if (blankStat) {
                lArgs.add("");
            } else {
                lArgs.add(statDesc);
            }
            if (tagInfo.isFloatValue()) {
                lArgs.add(stat.getStatMin());
            } else {
                lArgs.add((int) stat.getStatMin());
            }
            info = new BonusInfo(tagInfo);
            info.prefix = prefix;
            info.dmgFlat = true;
            tag = "TXT_INT";
            if (tagInfo.isFloatValue()) {
                tag = "TXT_FLOAT";
            }
            if ((tagInfo.isSignMandatory() || skillModifier != null) && stat.getStatMin() > 0.0f) {
                tag += "_PLUS";
            }
            if (tagInfo.isMinAsPerc()) {
                tag += "_PERC";
            }
            if (stat.getStatChance() > 0) {
                tag += "_CHANCE";
                lArgs.add(stat.getStatChance());
                info.dmgChance = true;
            }
            info.statDesc = statDesc;
            info.text = buildText(tag, lArgs);
            if (skillModifier != null) {
                String skillname = skillModifier.getSkillName();
                if (skillModifier.getMasteryName() != null) {
                    skillname = skillname + " (" + skillModifier.getMasteryName() + ")";
                }
                final Object[] args2 = {info.text, skillname};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_MODIFIER_TO_SKILL", args2);
            }
            infos.add(info);
        }
        if (stat.getStatModifier() != 0) {
            lArgs = new LinkedList<Object>();
            if (blankStat) {
                lArgs.add("");
            } else {
                lArgs.add(statDesc);
            }
            lArgs.add(adjustValue(item, detailType, stat.getStatModifier()));
            info = new BonusInfo(tagInfo);
            info.prefix = prefix;
            info.dmgPerc = true;
            tag = "TXT_PERC";
            if ((tagInfo.isSignMandatory() || skillModifier != null) && stat.getStatMin() > 0.0f) {
                tag += "_PLUS";
            }
            if (stat.getStatChance() > 0) {
                tag += "_CHANCE";
                lArgs.add(stat.getStatChance());
                info.dmgChance = true;
            }
            info.statDesc = statDesc;
            info.text = buildText(tag, lArgs);
            if (skillModifier != null) {
                String skillname = skillModifier.getSkillName();
                if (skillModifier.getMasteryName() != null) {
                    skillname = skillname + " (" + skillModifier.getMasteryName() + ")";
                }
                final Object[] args2 = {info.text, skillname};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_MODIFIER_TO_SKILL", args2);
            }
            infos.add(info);
        }
        return infos;
    }

    private static List<BonusInfo> parseDefense(final DBStashItem item, final int detailType, final DBStat stat, final String prefix, final DBSkillModifier skillModifier, final TagInfo tagInfo, final boolean blankStat) {
        final List<BonusInfo> infos = new LinkedList<BonusInfo>();
        String tag = null;
        List<Object> lArgs = null;
        BonusInfo info = null;
        String statDesc = GDMsgFormatter.getString(GDMsgFormatter.rbGD, tagInfo.getTag());
        if (prefix != null) {
            final Object[] args = {prefix, statDesc};
            statDesc = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_STAT_PREFIX", args);
        }
        if (stat.getStatMin() != 0.0f) {
            lArgs = new LinkedList<Object>();
            if (blankStat) {
                lArgs.add("");
            } else {
                lArgs.add(statDesc);
            }
            lArgs.add(adjustValue(item, detailType, (int) stat.getStatMin()));
            info = new BonusInfo(tagInfo);
            info.prefix = prefix;
            info.dmgFlat = true;
            tag = "TXT_INT";
            if ((tagInfo.isSignMandatory() || skillModifier != null) && stat.getStatMin() > 0.0f) {
                tag += "_PLUS";
            }
            if (tagInfo.isMinAsPerc()) {
                tag += "_PERC";
            }
            if (stat.getStatChance() > 0) {
                lArgs.add(stat.getStatChance());
                tag += "_CHANCE";
                if (tagInfo.getTag().equals("DEF_BLOCK_CHANCE")) {
                    tag = "TXT_DEF_UNI_SHIELD_BLOCK";
                    lArgs.clear();
                    lArgs.add(stat.getStatMin());
                    lArgs.add(stat.getStatChance());
                }
                info.dmgChance = true;
            }
            info.statDesc = statDesc;
            info.text = buildText(tag, lArgs);
            if (skillModifier != null) {
                String skillname = skillModifier.getSkillName();
                if (skillModifier.getMasteryName() != null) {
                    skillname = skillname + " (" + skillModifier.getMasteryName() + ")";
                }
                final Object[] args2 = {info.text, skillname};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_MODIFIER_TO_SKILL", args2);
            }
            infos.add(info);
        }
        if (stat.getStatModifier() != 0) {
            lArgs = new LinkedList<Object>();
            if (blankStat) {
                lArgs.add("");
            } else {
                lArgs.add(statDesc);
            }
            lArgs.add(adjustValue(item, detailType, stat.getStatModifier()));
            info = new BonusInfo(tagInfo);
            info.prefix = prefix;
            info.dmgPerc = true;
            tag = "TXT_DEF_PERC";
            info.statDesc = statDesc;
            info.text = buildText(tag, lArgs);
            if (skillModifier != null) {
                String skillname = skillModifier.getSkillName();
                if (skillModifier.getMasteryName() != null) {
                    skillname = skillname + " (" + skillModifier.getMasteryName() + ")";
                }
                final Object[] args2 = {info.text, skillname};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_MODIFIER_TO_SKILL", args2);
            }
            infos.add(info);
        }
        if (stat.getMinDuration() > 0) {
            statDesc = GDMsgFormatter.getString(GDMsgFormatter.rbGD, tagInfo.getTag() + "_DOT");
            if (prefix != null) {
                final Object[] args = {prefix, statDesc};
                statDesc = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_STAT_PREFIX", args);
            }
            lArgs = new LinkedList<Object>();
            if (blankStat) {
                lArgs.add("");
            } else {
                lArgs.add(statDesc);
            }
            lArgs.add(stat.getMinDuration());
            info = new BonusInfo(tagInfo);
            info.prefix = prefix;
            info.dmgPerc = true;
            tag = "TXT_DEF_DUR";
            info.statDesc = statDesc;
            info.text = buildText(tag, lArgs);
            if (skillModifier != null) {
                String skillname = skillModifier.getSkillName();
                if (skillModifier.getMasteryName() != null) {
                    skillname = skillname + " (" + skillModifier.getMasteryName() + ")";
                }
                final Object[] args2 = {info.text, skillname};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_MODIFIER_TO_SKILL", args2);
            }
            infos.add(info);
        }
        if (stat.getMaxResist() > 0) {
            lArgs = new LinkedList<Object>();
            if (blankStat) {
                lArgs.add("");
            } else {
                lArgs.add(statDesc);
            }
            lArgs.add(stat.getMaxResist());
            info = new BonusInfo(tagInfo);
            info.prefix = prefix;
            info.dmgPerc = true;
            info.dmgMaxResist = true;
            tag = "TXT_DEF_MAX";
            info.statDesc = statDesc;
            info.text = buildText(tag, lArgs);
            if (skillModifier != null) {
                String skillname = skillModifier.getSkillName();
                if (skillModifier.getMasteryName() != null) {
                    skillname = skillname + " (" + skillModifier.getMasteryName() + ")";
                }
                final Object[] args2 = {info.text, skillname};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_MODIFIER_TO_SKILL", args2);
            }
            infos.add(info);
        }
        return infos;
    }

    private static List<BonusInfo> parseOffense(final DBStashItem item, final int detailType, final DBStat stat, final String prefix, final DBSkillModifier skillModifier, final TagInfo tagInfo, final boolean blankStat) {
        final List<BonusInfo> infos = new LinkedList<BonusInfo>();
        String tag = null;
        List<Object> lArgs = null;
        BonusInfo info = new BonusInfo(tagInfo);
        String statDesc = GDMsgFormatter.getString(GDMsgFormatter.rbGD, tagInfo.getTag());
        if (prefix != null) {
            final Object[] args = {prefix, statDesc};
            statDesc = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_STAT_PREFIX", args);
        }
        if (statDesc.equals("")) {
            return infos;
        }
        if (stat.getStatMin() != 0.0f) {
            lArgs = new LinkedList<Object>();
            if (blankStat) {
                lArgs.add("");
            } else {
                lArgs.add(statDesc);
            }
            if (stat.getMinDuration() == 0) {
                lArgs.add(adjustValue(item, detailType, (int) stat.getStatMin()));
            } else if (tagInfo.isMinAsPerc()) {
                lArgs.add(adjustValue(item, detailType, (int) stat.getStatMin()));
            } else {
                lArgs.add(adjustValue(item, detailType, (int) stat.getStatMin() * stat.getMinDuration()));
                lArgs.add(adjustValue(item, detailType, (int) stat.getStatMin()));
            }
            info = new BonusInfo(tagInfo);
            info.prefix = prefix;
            info.dmgGlobal = stat.isGlobal();
            info.dmgXOR = stat.isXOR();
            info.dmgFlat = true;
            tag = "TXT_OFF_ABS";
            if ((tagInfo.isSignMandatory() || skillModifier != null) && stat.getStatMin() > 0.0f) {
                tag += "_PLUS";
            }
            if (tagInfo.isMinAsPerc()) {
                tag += "_PERC";
            }
            if (tagInfo.isMinAsDuration()) {
                tag += "_TIME";
            }
            if (stat.getStatMax() != 0.0f) {
                tag += "_RANGE";
                if (stat.getMinDuration() == 0) {
                    lArgs.add(adjustValue(item, detailType, (int) stat.getStatMax()));
                } else if (tagInfo.isMinAsPerc()) {
                    lArgs.add(adjustValue(item, detailType, (int) stat.getStatMax()));
                } else {
                    lArgs.add(adjustValue(item, detailType, (int) stat.getStatMax() * stat.getMinDuration()));
                    lArgs.add(adjustValue(item, detailType, (int) stat.getStatMax()));
                }
            }
            if (stat.getMinDuration() > 0) {
                tag += "_DUR";
                lArgs.add(stat.getMinDuration());
                info.dmgDuration = true;
            }
            if (stat.getStatChance() > 0) {
                if (stat.isGlobal()) {
                    if (stat.isXOR()) {
                        tag += "_CHANCE";
                        lArgs.add(stat.getStatChance());
                        info.dmgChance = true;
                    }
                } else {
                    tag += "_CHANCE";
                    lArgs.add(stat.getStatChance());
                    info.dmgChance = true;
                }
            }
            info.statDesc = statDesc;
            info.text = buildText(tag, lArgs);
            if (skillModifier != null) {
                String skillname = skillModifier.getSkillName();
                if (skillModifier.getMasteryName() != null) {
                    skillname = skillname + " (" + skillModifier.getMasteryName() + ")";
                }
                final Object[] args2 = {info.text, skillname};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_MODIFIER_TO_SKILL", args2);
            }
            infos.add(info);
        }
        if (stat.getStatModifier() != 0) {
            lArgs = new LinkedList<Object>();
            if (blankStat) {
                lArgs.add("");
            } else {
                lArgs.add(statDesc);
            }
            lArgs.add(adjustValue(item, detailType, stat.getStatModifier()));
            info = new BonusInfo(tagInfo);
            info.prefix = prefix;
            info.dmgGlobal = stat.isGlobal();
            info.dmgXOR = stat.isXOR();
            info.dmgPerc = true;
            tag = "TXT_OFF_PERC";
            if (stat.getDurationModifier() > 0) {
                tag += "_DUR";
                lArgs.add(stat.getDurationModifier());
            }
            if (stat.getStatModifierChance() > 0) {
                tag += "_CHANCE";
                lArgs.add(stat.getStatModifierChance());
                info.dmgChance = true;
            }
            info.statDesc = statDesc;
            info.text = buildText(tag, lArgs);
            if (skillModifier != null) {
                String skillname = skillModifier.getSkillName();
                if (skillModifier.getMasteryName() != null) {
                    skillname = skillname + " (" + skillModifier.getMasteryName() + ")";
                }
                final Object[] args2 = {info.text, skillname};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_MODIFIER_TO_SKILL", args2);
            }
            infos.add(info);
        }
        return infos;
    }

    private static List<BonusInfo> parseStat(final DBStashItem item, final int detailType, final DBStat stat, final String prefix, final DBSkillModifier skillModifier, final TagInfo tagInfo, final boolean blankStat) {
        if (tagInfo.getTag().equals("TXT_UNI_RACE_DAMAGE")) {
            return fillRaceBonus(detailType, stat, prefix, tagInfo, blankStat);
        }
        final int infoType = tagInfo.getInfoType();
        switch (infoType) {
            case 4: {
                return parseCharStat(item, detailType, stat, prefix, skillModifier, tagInfo, blankStat);
            }
            case 1: {
                return parseDefense(item, detailType, stat, prefix, skillModifier, tagInfo, blankStat);
            }
            case 2: {
                return parseOffense(item, detailType, stat, prefix, skillModifier, tagInfo, blankStat);
            }
            case 3: {
                return parseOffense(item, detailType, stat, prefix, skillModifier, tagInfo, blankStat);
            }
            default: {
                return null;
            }
        }
    }

    private static List<BonusInfo> parseStat(final DBStat stat, final TagInfo tagInfo, final boolean blankStat) {
        final int infoType = tagInfo.getInfoType();
        switch (infoType) {
            case 4: {
                return parseCharStat(null, 3, stat, null, null, tagInfo, blankStat);
            }
            case 1: {
                return parseDefense(null, 3, stat, null, null, tagInfo, blankStat);
            }
            case 2: {
                return parseOffense(null, 3, stat, null, null, tagInfo, blankStat);
            }
            case 3: {
                return parseOffense(null, 3, stat, null, null, tagInfo, blankStat);
            }
            default: {
                return null;
            }
        }
    }

    private static List<BonusInfo> parseStat(final DBStat stat, final TagInfo tagInfo, final String prefix, final boolean blankStat) {
        final int infoType = tagInfo.getInfoType();
        switch (infoType) {
            case 4: {
                return parseCharStat(null, 3, stat, prefix, null, tagInfo, blankStat);
            }
            case 1: {
                return parseDefense(null, 3, stat, prefix, null, tagInfo, blankStat);
            }
            case 2: {
                return parseOffense(null, 3, stat, prefix, null, tagInfo, blankStat);
            }
            case 3: {
                return parseOffense(null, 3, stat, prefix, null, tagInfo, blankStat);
            }
            default: {
                return null;
            }
        }
    }

    private static BonusInfo getStatInfo(final DBStashItem item, final int detailType, final String statType, final String prefix, final int value, final boolean isPercent) {
        return getStatInfo(item, detailType, statType, prefix, value, 0, isPercent);
    }

    private static BonusInfo getStatInfo(final DBStashItem item, final int detailType, final String statType, final String prefix, final int value, final int chance, final boolean isPercent) {
        final TagInfo tagInfo = TagInfoHashMap.getInfo(statType);
        if (tagInfo == null) {
            return null;
        }
        BonusInfo info = new BonusInfo(tagInfo);
        String tag = null;
        if (isPercent) {
            tag = "TXT_PERC_PLUS";
        } else {
            tag = "TXT_ABS_PLUS";
        }
        String stat = GDMsgFormatter.getString(GDMsgFormatter.rbGD, statType);
        if (prefix != null) {
            final Object[] args = {prefix, stat};
            stat = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_STAT_PREFIX", args);
        }
        try {
            if (chance == 0) {
                final Object[] args = {stat, adjustValue(item, detailType, value)};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, tag, args);
                info.tag = statType;
                info.prefix = prefix;
                info.bonusPerc = isPercent;
            } else {
                tag += "_CHANCE";
                final Object[] args = {stat, adjustValue(item, detailType, value), chance};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, tag, args);
                info.tag = statType;
                info.prefix = prefix;
                info.bonusPerc = isPercent;
            }
        } catch (IllegalArgumentException ex) {
            final Object[] errargs = {tag, "GrimDawn"};
            final String msg = GDMsgFormatter.format(GDMsgFormatter.rbMsg, "ERR_PROP_TAG_ARGS", errargs);
            GDMsgLogger.addError(msg);
            info = null;
        }
        return info;
    }

    private void createSkillBonusInfos(final DBStashItem item) {
        final DBSkillBonus bonus = (DBSkillBonus) this.entity;
        int value = 0;
        if (item == null) {
            value = bonus.getValue();
        } else if (item.isComponent()) {
            value = bonus.getValueForLevel(item.getComponentPieces() - 1);
        } else {
            value = bonus.getValue();
        }
        if (value > 0) {
            final BonusInfo info = new BonusInfo();
            String skillname = bonus.getEntityName();
            if (bonus.getMasteryName() != null) {
                skillname = skillname + " (" + bonus.getMasteryName() + ")";
            }
            if (bonus.getSkillBonusType() == 3) {
                info.sbMastery = false;
                info.sbPlus = 0;
                final DBSkill skill = DBSkill.get(bonus.getEntity());
                if (skill != null) {
                    info.text = DetailComposer.getSkillDescription(null, skill, value, null);
                    this.add(info);
                } else if (skillname != null) {
                    final Object[] args = {skillname};
                    info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_SKILL_GRANTED", args);
                    this.add(info);
                }
            } else if (bonus.getSkillBonusType() == 4) {
                final Object[] args2 = {value};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_PLUS_ALLSKILLS", args2);
                info.sbMastery = false;
                info.sbPlus = value;
            } else if (skillname != null) {
                final Object[] args2 = {value, skillname};
                info.text = GDMsgFormatter.format(GDMsgFormatter.rbGD, "TXT_SKILL_BONUS", args2);
                info.sbMastery = (bonus.getSkillBonusType() == 1);
                info.sbPlus = value;
                this.add(info);
            }
        }
    }

    public static List<BonusInfo> createSkillInfos(final DBSkill skill, final DBStat stat) {
        if (stat.getStatType() == null) {
            return null;
        }
        final TagInfo info = TagInfoHashMap.getInfo(stat.getStatType());
        if (info == null) {
            return null;
        }
        if (info.getTag() != null) {
            return parseStat(stat, info, false);
        }
        return null;
    }

    public static List<BonusInfo> createSkillInfos(final DBSkill skill, final DBStat stat, final String prefix) {
        if (stat.getStatType() == null) {
            return null;
        }
        final TagInfo info = TagInfoHashMap.getInfo(stat.getStatType());
        if (info == null) {
            return null;
        }
        if (info.getTag() != null) {
            return parseStat(stat, info, prefix, false);
        }
        return null;
    }

    private void add(final BonusInfo info) {
        if (info == null) {
            return;
        }
        if (info.text != null) {
            this.infos.add(info);
        }
    }

    private void createSkillModifierInfos() {
        final DBSkillModifier sm = (DBSkillModifier) this.entity;
        final String skillName = sm.getSkillName();
        if (skillName != null) {
            for (final DBStat stat : sm.getModifierStatList()) {
                final List<BonusInfo> list = createStatInfos(null, 1, stat, sm);
                if (list != null) {
                    for (final BonusInfo info : list) {
                        this.add(info);
                    }
                }
            }
        }
    }
}
